/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	Material.h
*
*	Description -	Material.
*
*	Comments	-
*
*	Modification History:
*			Name			   Date					Description
*			MrCodeSushi	-	06/05/2011	-	Creation of this file
**************************************************************************************/
#ifndef _PSX_MATERIAL_H_
#define _PSX_MATERIAL_H_

#include "PulseSTD.h"
#include "ResourcePoolItem.h"
#include "StoragePool.h"
#include "GraphicsTypes.h"
#include "Effect.h"
#include "ParameterContainer.h"
#include "Array.h"

namespace Pulse
{
	struct MaterialDesc : public BaseResDesc
	{
	public:

		void SetToLoad( const CHAR *pFilename ) { m_filename = pFilename; }

		virtual const ResourceCode GetType( void ) const { return ResourceCode( EResource::VIDEO, EVideoResource::MATERIAL ); }

		String m_filename;
	};

	struct SubMaterial
	{
		ParameterContainer	m_params;
	};

	class Material : public IResourcePoolItem
	{
	public:

		virtual ~Material( void );

		// These defines the base interface for all derived resources
		virtual BOOL CreateResource( BaseResDesc *pDesc );
		virtual BOOL DestroyResource( void );
		virtual BOOL LoadResource( void );
		virtual BOOL UnloadResource( void );

		virtual const ResourceCode GetType( void ) const { return ResourceCode( EResource::VIDEO, EVideoResource::MATERIAL ); }

	public:

		// Material methods

		Effect * GetEffect( void );

		BOOL IsMaterialElementAvailable( EParameter::Type Type, const CHAR *pName );

		// TODO: Make this function generic to accept any parametercontainer to accomodate sub-material params
		IParameterBinder * GetMaterialElemendBinder( EParameter::Type type, const CHAR *pName );

		ParameterContainer * GetMaterialParameters( void ) { return &m_params; }

		ParameterContainer * GetSubMaterialParameters( UPOS_T index );

		// NOTE: pResSysName is a parameter name defined in the GlobalGraphicsString.
		EErrorCode::Type AddParameter( const CHAR *pResSysName, Texture2D *pRes );

	private:

		PSX_MakeStoragePoolFriend( Material );

		Material( void );

		EErrorCode::Type Initialize( void );

		void Cleanup( void );

	private:

		// File processing methods
		EErrorCode::Type ProcessMaterial( XMLElementPtr pElem );

		EErrorCode::Type ProcessEffect( XMLElementPtr pElem );

		EErrorCode::Type ProcessParameters( XMLElementPtr pElem, ParameterContainer *pParams );

		EErrorCode::Type ProcessSubMaterials( XMLElementPtr pElem );

		// TODO: Make this method generic. Not as part of this material class.
		BOOL IsMaterialElementInContainer( ParameterContainer *pContainer, EParameter::Type type, const CHAR *pName );

	private:

		typedef Array<SubMaterial*> SubMaterialList;

		MaterialDesc		m_desc;
		Effect				*m_pEffect;
		ParameterContainer	m_params;
		SubMaterialList		m_subMaterials;

	};
}

#endif /* _PSX_MATERIAL_H_ */